clear();
clc();
close all;                              %Plots schließen

%KONFIGURATION---------------------------------------------------------------------
aWERTETABELLE(1,:)  =["Xi",-1, 0,1, 2];
aWERTETABELLE(2,:)  =["Fi", 5,-2,9,-4];
xACHSE              = @(x) 0*x;
sKommastellenDouble = '%.0f';          %Nachkommastellen, die in einer Berechnung mitgeschleift werden sollen

%PRUEFUNG--------------------------------------------------------------------------
iANZAHL_WERTE = size(aWERTETABELLE,2)-1;                                            %Gibt die Anzahl der Spalten zurück (Parameter 2) abzüglich 1 (Der Bezeichner der Wertereihe)

%INITIALISIERUNG-------------------------------------------------------------------
aDIVDIFF(1,:)=["Xi","Fi"];
Speicher = "F[Xi";
for(i=3:1:(iANZAHL_WERTE+2-1))                                                      %Erzeugung der dynamischen Kopfzeile
    Speicher = strcat(Speicher,",Xi+",num2str(i-2));
    aDIVDIFF(1,i)=[strcat(Speicher,"]")];
end
aDIVDIFF(2:(2*iANZAHL_WERTE),1:((iANZAHL_WERTE)+1))=[""];                           %Auffüllung des Arrays mit leeren Strings

%BERECHNUNG_DER_DIVIDIERENDEN_DIFFERENZEN------------------------------------------
for(i=1:1:iANZAHL_WERTE)                                                            %Übertragung der Wertetabelle in die differierenden-Differenzen-Tabelle
    aDIVDIFF(2*i,1)=aWERTETABELLE(1,i+1);
    aDIVDIFF(2*i,2)=aWERTETABELLE(2,i+1);
end
for(i=1:1:iANZAHL_WERTE-1)                                                          %Definiert das Durchlaufen der Berechnungsspalten
    for(j=2+i:2:(2*iANZAHL_WERTE)-i)                                                %Definiert das Durchlaufen der Berechnungszeilen
        aDIVDIFF(j,2+i)=num2str((str2double(aDIVDIFF(j+1,1+i))-str2double(aDIVDIFF(j-1,1+i)))/(str2double(aDIVDIFF(j+i,1))-str2double(aDIVDIFF(j-i,1))),sKommastellenDouble);
    end
end
disp(aDIVDIFF);

%BERECHNUNG_DER_NEWTON'SCHEN_INTERPOLATIONSFORMEL----------------------------------
aINTERPOLATIONSFORMEL(1,1)=["P(x)="];
Speicher="";
for(i=1:1:iANZAHL_WERTE) 
    aINTERPOLATIONSFORMEL(1,1+i)=strcat("A",num2str(i-1),Speicher);
    Speicher=strcat(Speicher,"*(X-X",num2str(i-1),")");
end
aINTERPOLATIONSFORMEL(2,1)=["P(x)="];
Speicher="";
for(i=1:1:iANZAHL_WERTE) 
    aINTERPOLATIONSFORMEL(2,1+i)=strcat(aDIVDIFF(1+i,1+i),Speicher);
    Speicher=strcat(Speicher,"*(X-",aDIVDIFF(2*i,1),")");
end
%-------------
%Initialisierung der Hilfs matrix A und X
for(i=1:1:iANZAHL_WERTE) 
    A_WERTE(i)=str2double(aDIVDIFF(1+i,1+i));
    X_WERTE(i)=str2double(aDIVDIFF(2*i,1));
end
%Befüllen der Diagonalen der X-Maske
aX_MASKE=eye(iANZAHL_WERTE,iANZAHL_WERTE);  %Hauptdiagonale mit 1 befüllt
for(i=1:1:iANZAHL_WERTE-1)                  %Anzahl der Diagonalen unter Hauptdiagonalen um 1 kleiner als Anzahl als beide Matrixdimensionen
    for(j=1:1:iANZAHL_WERTE-i)              %Zählt die Anzahl der Werte einer Hauptdiagonalen (die erste Diagnonale hat 3 bei 4 Werten; die zweite hat 2 bei 4 Werten)
        A=[0:j-1+i-1];                      %j-1 setzt die Variable auf den Startwert 0 statt 1; +i-1 ist + Diagonale -1
        B=perms(A);                         %erzeugt Alle möglichen Kombinationen der aufsteigenden X-Indexe in A
        C=B(1:end,1:i);                     %schneidet von den Kombinationen Spalten ab
        for(k=1:1:size(C,1))
           C(k,:)=sort(C(k,:),'ascend');    %sortiert jede einzelne Zeile mit den Wrten aufsteigend
        end
        C=unique(C,'rows');                 %löscht Duplikate von Zeilen
        Zwischenspeicher_Summanden=0;
        for(k=1:1:size(C,1))
            Zwischenspeicher_Faktoren=1;
            for(l=1:1:size(C,2))
                Zwischenspeicher_Faktoren=Zwischenspeicher_Faktoren*X_WERTE(C(k,l)+1);
            end
            Zwischenspeicher_Summanden=Zwischenspeicher_Summanden+Zwischenspeicher_Faktoren;
        end
        aX_MASKE(j+i,j)=Zwischenspeicher_Summanden;
    end
end
%Befüllen der Diagonalen der A-Maske
for(i=1:1:iANZAHL_WERTE)
    for(j=0:1:iANZAHL_WERTE-i)
        if(mod(i,2)~=0)
            aA_MASKE(j+i,j+1)=A_WERTE(i+j);            
        else
            aA_MASKE(j+i,j+1)=-A_WERTE(i+j);
        end
    end
end
%Multiplizieren der X-Maske mit A-Maske
for(i=1:1:iANZAHL_WERTE)
    for(j=1:1:iANZAHL_WERTE)
        AX_WERTE(i,j)=aA_MASKE(i,j)*aX_MASKE(i,j);
    end
end
%Summieren zum Endergebnis
for(i=1:1:iANZAHL_WERTE)
    INTERPOLATIONSFORMEL(i)=0;
    for(j=1:1:iANZAHL_WERTE)
        INTERPOLATIONSFORMEL(i)=INTERPOLATIONSFORMEL(i)+AX_WERTE(j,i)
    end
end
%-------------



aINTERPOLATIONSFORMEL(3,1)=["Schritt0"];
for(i=1:1:iANZAHL_WERTE) 
    aINTERPOLATIONSFORMEL(3,1+i)=aDIVDIFF(1+i,1+i);
end
for(i=1:1:iANZAHL_WERTE)
    aINTERPOLATIONSFORMEL(3+i,1)=[strcat("Schritt",num2str(i))];
    for(j=0:1:i-1) 
        switch(j)
            case 0
                aINTERPOLATIONSFORMEL(3+i,2)=aINTERPOLATIONSFORMEL(3,2);
            case 1
                aINTERPOLATIONSFORMEL(3+i,2)=str2double(aINTERPOLATIONSFORMEL(3+j,2))-(str2double(aINTERPOLATIONSFORMEL(3,3))*str2double(aDIVDIFF(2,1)));                
                aINTERPOLATIONSFORMEL(3+i,3)=aINTERPOLATIONSFORMEL(3,3);
            case 2
                aINTERPOLATIONSFORMEL(3+i,2)=str2double(aINTERPOLATIONSFORMEL(3+j,2))+(str2double(aINTERPOLATIONSFORMEL(3,4))*str2double(aDIVDIFF(2,1))*str2double(aDIVDIFF(4,1)));              
                aINTERPOLATIONSFORMEL(3+i,3)=str2double(aINTERPOLATIONSFORMEL(3+j,3))-(str2double(aINTERPOLATIONSFORMEL(3,4))*(str2double(aDIVDIFF(2,1))+str2double(aDIVDIFF(4,1))));
                aINTERPOLATIONSFORMEL(3+i,4)=aINTERPOLATIONSFORMEL(3,4);
            case 3
                aINTERPOLATIONSFORMEL(3+i,2)=str2double(aINTERPOLATIONSFORMEL(3+j,2))-(str2double(aINTERPOLATIONSFORMEL(3,5))*str2double(aDIVDIFF(2,1))*str2double(aDIVDIFF(4,1))*str2double(aDIVDIFF(6,1)));
                aINTERPOLATIONSFORMEL(3+i,3)=str2double(aINTERPOLATIONSFORMEL(3+j,3))+(str2double(aINTERPOLATIONSFORMEL(3,5))*((str2double(aDIVDIFF(2,1))*str2double(aDIVDIFF(4,1)))+(str2double(aDIVDIFF(2,1))*str2double(aDIVDIFF(6,1)))+(str2double(aDIVDIFF(4,1))*str2double(aDIVDIFF(6,1)))));
                aINTERPOLATIONSFORMEL(3+i,4)=str2double(aINTERPOLATIONSFORMEL(3+j,4))-(str2double(aINTERPOLATIONSFORMEL(3,5))*(str2double(aDIVDIFF(2,1))+str2double(aDIVDIFF(4,1))+str2double(aDIVDIFF(6,1))));
                aINTERPOLATIONSFORMEL(3+i,5)=aINTERPOLATIONSFORMEL(3,5);
            otherwise
        end
    end
end
LetzteZeile=size(aINTERPOLATIONSFORMEL,1)+1;
aINTERPOLATIONSFORMEL(LetzteZeile,1)=["P(x)="];
for(i=1:1:iANZAHL_WERTE) 
    aINTERPOLATIONSFORMEL(LetzteZeile,1+i)=strcat(aINTERPOLATIONSFORMEL(LetzteZeile-1,1+i),"*X^",num2str(i-1));
end
disp(aINTERPOLATIONSFORMEL);

%{
%FUNKTIONSPLOT---------------------------------------------------------------------
Inkrement=100;
X=min(str2double(aWERTETABELLE(1,2:end))):(max(str2double(aWERTETABELLE(1,2:end)))-min(str2double(aWERTETABELLE(1,2:end))))/Inkrement:max(str2double(aWERTETABELLE(1,2:end)));
for(i=1:1:Inkrement+1)
    Y(i)=0;
    for(j=1:1:iANZAHL_WERTE) 
        Y(i)=Y(i)+str2double(aINTERPOLATIONSFORMEL(LetzteZeile-1,1+j))*(X(i)^(j-1));
    end 
end
plot(X,Y,'color','blue');
hold on;                                %Warten bis zur Plotausgabe
plot(X,xACHSE(X),'color','black');
grid on;
grid minor;
%}

%PROGRAMMENDE----------------------------------------------------------------------
%clearvars -except aWERTETABELLE aDIVDIFF aINTERPOLATIONSFORMEL                     %Workspace aufräumen
